package main.java.chessfootball.rules;

import main.java.chessfootball.model.exception.RuleViolationException;
import main.java.chessfootball.model.game.Ball;
import main.java.chessfootball.model.game.Cell;
import main.java.chessfootball.model.game.Game;
import main.java.chessfootball.model.game.Player;
import main.java.chessfootball.model.play.Move;
import main.java.chessfootball.model.play.Put;
import main.java.chessfootball.model.play.Turn;
import main.java.chessfootball.rules.checker.*;

/**
 * User: Igor
 * Date: 12.06.2011
 * Time: 6:55:26
 */
public class RuleChecker
{
	public static AbstractChecker[] putChecks = {new PlayerAreaChecker(), new PlayerClashChecker(), new OutGameAreaChecker(), new PutLimitChecker()};
	public static AbstractChecker[] moveChecks = {new PlayerAreaChecker(), new PlayerClashChecker(), new BallAreaChecker(), new BallClashChecker()
			, new MoveLimitChecker(), new KickChecker(), new GoalkeeperChecker(), new OffsideChecker()};
	public static AbstractChecker[] turnChecks = {new TurnChecker()};

	private void check(Game game, Move move, Put put, Cell moveBallToCell, AbstractChecker[] checks) throws RuleViolationException
	{
		for (AbstractChecker checker : checks)
		{
			checker.setGame(game);
			if (checker instanceof AbstractPutChecker)
			{
				((AbstractPutChecker)checker).setPut(put);
			}
			if (checker instanceof AbstractBallChecker)
			{
				((AbstractBallChecker)checker).setMoveBallToCell(moveBallToCell);
			}
			if (checker instanceof AbstractMoveChecker)
			{
				((AbstractMoveChecker)checker).setMove(move);
			}
			checker.check();
		}
	}

	public void checkMove(Game game, Move move) throws RuleViolationException
	{
		Ball ball = game.getField().getBall();
		Player player = game.getField().getPlayer(move.getSide(), move.getPlayer());
		Cell moveBallToCell = ball.getCell();
		if (move.getVector().getCell(player.getCell(), 1).equals(ball.getCell()))
		{
			moveBallToCell = move.getVector().getCell(ball.getCell(), move.getLength());
		}
		check(game, move
				, new Put(move.getSide(), move.getPlayer(), move.getVector().getCell(game.getField().getTeam(move.getSide()).getPlayer(move.getPlayer()).getCell(), 1))
				, moveBallToCell
				, moveChecks);
	}

	public void checkTurn(Game game, Turn turn)
	{
		//todo
	}

	public void checkTurn(Game game) throws RuleViolationException
	{
		check(game, null, null, null, turnChecks);
	}

	public void checkPut(Game game, Put put) throws RuleViolationException
	{
		check(game, null, put, null, putChecks);
	}

}
